/*
desc    :任务事件类
function:
        keep, 统计结果是否是保存在自己身上, 不需要stat直接修改值
        operate, 结果操作类型, inc/add/max/set
        matching(user, goalConf, arg), 判断是否匹配检测条件
        stat(user, goalConf), 计算检测结果
*/

var eventModules = {};

eventModules.DoWorldBossAttack = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.DoRoleRefine = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.DoServerMineWin = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.DoTroopMatchWin = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return arg == goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.DoMergeGem = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return arg == goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.DoTavernEnroll = {
    operate: 'inc',

    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.Duplicate = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.duplicate;
    },
}

eventModules.MyDuplicate = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.myBattle.max;
    },
}

eventModules.FightForce = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.status.fight_force;
    },
}

eventModules.HaveRole = {
    matching: function(user, goalConf, arg) { 
        return true;
    },

    stat: function(user, goalConf) {
        return Object.keys(user.role).length;
    },
}

eventModules.HaveGodRole = {
    matching: function(user, goalConf, arg) { 
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            if (roles[rid].god >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveWingRole = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            if (roles[rid].wing >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveStarRole = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            if (roles[rid].star >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveLevelRole = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            if (roles[rid].level >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveSoldierLevelRole = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            if (roles[rid].soldier_level >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.RoleGrouthSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var count = 0;
        for (var rid in roles) {
            count += (roles[rid].grouth || 0);
        }
        return count;
    },
}

eventModules.RoleSoulSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var count = 0;
        for (var rid in roles) {
            count += (roles[rid].soul || 0);
        }
        return count;
    },
}

eventModules.RoleRefineSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var count = 0;
        for (var rid in roles) {
            var role = roles[rid];
            count += (role.attack||0);
            count += (role.defence||0);
            count += (role.mdefence||0);
        }
        return count;
    },
}

eventModules.RoleSkillSum = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var roles = user.role;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var rid in roles) {
            var skills = roles[rid].skill_levels;
            for (var skillId in skills) {
                if (skills[skillId] >= goalArg) {
                    count++;
                }
            }
        }
        return count;
    },
}

eventModules.RoleEquipStrengthSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf, arg) {
        var strengthSum = 0;
        if (arg) {
            var role = user.role[arg];
            var equips = [role.weapon, role.armor, role.accessory];
            equips.forEach(function(eid) {
                var equip = user.equip[eid];
                if (equip) {
                    strengthSum += (equip.strength || 0);
                }
            });
        } else {
            for (var rid in user.role) {
                strengthSum = Math.max(strengthSum, this.stat(user, goalConf, rid));
            }
        }

        return strengthSum;
    },
}

eventModules.RoleEquipStrengthAll = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf, arg) {
        var result = 0;
        if (arg) {
            var role = user.role[arg];
            var equips = [role.weapon, role.armor, role.accessory];
            for (var i = 0, len = equips.length; i < len; ++i) {
                var eid = equips[i];
                if (!eid) {
                    result = 0; break;
                }

                var equip = user.equip[eid];
                if (!equip || !equip.strength) {
                    result = 0; break;
                }

                result = i ? Math.min(result, equip.strength) : equip.strength;
            }
        } else {
            for (var rid in user.role) {
                result = Math.max(result, this.stat(user, goalConf, rid));
            }
        }

        return Math.max(0, result);
    },
}

eventModules.RoleEquipLevelSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf, arg) {
        var levelSum = 0;

        if (arg) {
            var role = user.role[arg];
            var equips = [role.weapon, role.armor, role.accessory];
            equips.forEach(function(eid) {
                var equip = user.equip[eid];
                if (equip) {
                    levelSum += (equip.level || 0);
                }
            });
        } else {
            for (var rid in user.role) {
                levelSum = Math.max(levelSum, this.stat(user, goalConf, rid));
            }
        }

        return levelSum;
    },
}

eventModules.RoleEquipLevelAll = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf, arg) {
        var result = 0;
        if (arg) {
            var role = user.role[arg];
            var equips = [role.weapon, role.armor, role.accessory];
            for (var i = 0, len = equips.length; i < len; ++i) {
                var eid = equips[i];
                if (!eid) {
                    result = 0; break;
                }

                var equip = user.equip[eid];
                if (!equip || !equip.level) {
                    result = 0; break;
                }

                result = i ? Math.min(result, equip.level) : equip.level;
            }
        } else {
            for (var rid in user.role) {
                result = Math.max(result, this.stat(user, goalConf, rid));
            }
        }

        return Math.max(0, result);
    },
}

eventModules.HaveHorse = {
    matching: function(user, goalConf, arg) {
        return arg == goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var horses = user.ride.horse;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var id in horses) {
            var horseId = horses[id].horse_id;
            var quantity = gConfHorse[horseId].Quantity;
            if (quantity == goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveStrengthEquip = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var equips = user.equip;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var id in equips) {
            if (equips[id].strength >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveLevelEquip = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var equips = user.equip;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var id in equips) {
            if (equips[id].level >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.HaveStarEquip = {
    matching: function(user, goalConf, arg) {
        return arg >= goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        var equips = user.equip;
        var goalArg = goalConf.GoalArg;
        var count = 0;
        for (var id in equips) {
            if (equips[id].star >= goalArg) {
                count++;
            }
        }
        return count;
    },
}

eventModules.UserLevel = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.status.level;
    },
}

eventModules.PetLevel = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.pet ? user.pet.level : 0;
    },
}

eventModules.TowerLevel = {
    matching: function(user, goalConf, arg) {
        return arg == goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        return user.tower.highest[goalConf.GoalArg] || 0;
    },
}

eventModules.KillGeneralLevel = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return user.kill.maxProgress || (user.kill.progress -1) || 0;
    },
}

eventModules.SmashLandTotalScore = {
    operate: 'add',

    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        return 0;
    },
}

eventModules.HeroLogLevel2 = {
    matching: function(user, goalConf, arg) {
        return arg == goalConf.GoalArg;
    },

    stat: function(user, goalConf) {
        if (!user.hero_log) {
            return 0;
        }

        var chapter = user.hero_log.chapters[goalConf.GoalArg];
        if (!chapter)
            return 0;

        var level2Pass = 0;
        for (var x=1; x<=8; ++x) {
            if (chapter[x].state == 4) {
                ++level2Pass;
            }
        }

        return level2Pass;
    },
};

eventModules.HoroscopeSum = {
    matching: function(user, goalConf, arg) {
        return true;
    },

    stat: function(user, goalConf) {
        var starSum = 0;
        for (var rid in user.role) {
            var horoscope = user.role[rid]['horoscope'];
            if (!horoscope)
                continue;

            starSum += Object.keys(horoscope.grids).length;
        }
        return starSum;
    },
};

for (var name in eventModules) {
    var eventClass = eventModules[name];

    eventClass.getValue = function(user, oldValue, goalConf, arg) {
        var newValue = oldValue;
        switch (this.operate) {
            case 'inc':
                newValue += 1;
                break;
            case 'add':
                newValue += (arg || 1);
                break;
            case 'max':
                newValue = Math.max(oldValue, (arg || 1));
                break;
            default:
                newValue = this.stat(user, goalConf, arg);
                break;
        }
        return newValue;    
    }

    exports[name] = eventClass;
}

